package bytedance;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntConsumer;

public class ZeroAndEvenOdd {
    private AtomicInteger current;
    private AtomicInteger num;
    private volatile boolean flag ;
    private volatile boolean printZeroo;
    private volatile boolean printedZero;

    public ZeroAndEvenOdd(int num){
        current = new AtomicInteger(1);
        this.num = new AtomicInteger(num);
        this.flag = true;
        this.printZeroo = false;
        this.printedZero = false;
    }

    public void printZero(IntConsumer printZero){
        while (flag){
            if(printZeroo){
                synchronized (this){
                printZero.accept(0);
                printedZero = true;
                printZeroo=false;
            }
        }}

    }

    public  void printOdd(IntConsumer printOdd){
        while (flag){
            if(current.get()%2==1){
                synchronized (this){
                if(current.get()>9){
                    printOdd.accept(current.get());
                    current.addAndGet(1);

                }else {
                    if(printedZero){
                        printOdd.accept(current.get());
                        current.addAndGet(1);

                        printedZero=false;
                    }else {
                        printZeroo = true;
                    }
                }
                check();
            }}
        }
    }

    public  void printEven(IntConsumer printEven){
        while (flag){
            if(current.get()%2==0){
                synchronized (this){
                if(current.get()>9){
                    printEven.accept(current.intValue());
                    current.addAndGet(1);
                }else {
                    if(printedZero){
                        printEven.accept(current.intValue());
                        current.addAndGet(1);
                        printedZero = false;
                    }else {
                        this.printZeroo = true;
                    }
                }
                check();
            }}
        }
    }

    private void check(){
        if(current.get() > num.get()){
            flag = false;
        }
    }

    public static void main(String[] args) {
        ZeroAndEvenOdd zeroAndEvenOdd = new ZeroAndEvenOdd(7);
        new Thread(()->{
            zeroAndEvenOdd.printZero(System.out::print);
        }).start();
        new Thread(()->{
            zeroAndEvenOdd.printEven(System.out::print);
        }).start();
        new Thread(()->{
            zeroAndEvenOdd.printOdd(System.out::print);
        }).start();
    }
}
